package com.chinamsp.codegen.convert.db;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.chinamsp.codegen.convert.BaseCodeGenProcessor;
import com.chinamsp.codegen.convert.CodeGenContext;
import com.chinamsp.codegen.convert.db.biz.TableColumnBiz;
import com.chinamsp.codegen.convert.db.dto.DBCodeGenContextBuilder;
import com.chinamsp.codegen.convert.db.dto.DBCodeGenProperty;
import com.chinamsp.codegen.convert.db.model.TableColumn;

/**
 * biz/model/dao的自动代码生成服务，包括 mode dao biz
 * @author shifenghu
 *
 */
public class DbCodeGenProcessor implements BaseCodeGenProcessor {

	@Autowired
	private DbCodeGenProperties properties;
	
	@Autowired
	private TableColumnBiz tableColumnBiz;
	
	@Override
	public void build(CodeGenContext context) {
		// 获取本次需要处理的  table
		Map<String, List<TableColumn>> tables = tableColumnBiz.findBySchema(
				properties.getSchema(), 
				StringUtils.isBlank(properties.getIncludes())? null : Arrays.asList(properties.getIncludes().split(",")), 
				StringUtils.isBlank(properties.getExclusions())? null : Arrays.asList(properties.getExclusions().split(","))
				);
		tables.forEach((name, columns) ->{
			LOGGER.info("开始处理 {} 数据表", name);
			this.build(name, columns, context);
			LOGGER.info("处理 {} 数据表成功", name);
		});
		
	}
	
	/**
	 * 逐个表处理
	 * @param tableName
	 * @param columns
	 * @param context
	 */
	private void build(String tableName, List<TableColumn> columns, CodeGenContext context) {
		final DBCodeGenContextBuilder builder = new DBCodeGenContextBuilder(tableName, properties.getPackageName());
		// 生成属性
		columns.forEach(col -> {
			builder.addProperty(new DBCodeGenProperty(col.getColumnName(), col.getDataType(), col.getColumnComment()));
		});
		// 生成基础目录
		String dir = DbCodeGenUtils.packageToPath(properties.getPackageName()) + File.separator;
		// 生成 context
		Map<String, Object> renderContext = builder.build();
		// 生成 model
		try {
			context.build(dir + MODEL_NAME , builder.className() + JAVA_EXT, MODEL_TMPLATE, renderContext);
		} catch (IOException e) {
			throw new IllegalArgumentException(e);
		}
		// 生成 dao
		try {
			context.build(dir + DAO_NAME.toLowerCase() , builder.className() + DAO_NAME + JAVA_EXT, DAO_TEMPLATE, renderContext);
		} catch (IOException e) {
			throw new IllegalArgumentException(e);
		}
		// 生成biz
		try {
			context.build(dir + BIZ_NAME.toLowerCase() , builder.className() + BIZ_NAME + JAVA_EXT, BIZ_TEMPLATE, renderContext);
		} catch (IOException e) {
			throw new IllegalArgumentException(e);
		}
	}
	
	/**
	 * model 模板文件
	 */
	private static final String MODEL_TMPLATE = "templates/db-model.tm";
	
	/**
	 * dao 模板文件
	 */
	private static final String DAO_TEMPLATE = "templates/db-dao.tm";
	
	/**
	 * biz 模板文件
	 */
	private static final String BIZ_TEMPLATE = "templates/db-biz.tm";
	
	private static final String MODEL_NAME = "model";
	private static final String DAO_NAME = "Dao";
	private static final String BIZ_NAME = "Biz";
	private static final String JAVA_EXT = ".java";
	
	private static final Logger LOGGER = LoggerFactory.getLogger(DbCodeGenProcessor.class);
	
}
